package com.yn.service.zy.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.yn.common.exception.TransitException;
import com.yn.common.model.article.ArticleContent;
import com.yn.common.model.zy.DoctorDepartmentLink;
import com.yn.common.model.zy.OrganDepartment;
import com.yn.common.model.zy.TDoctorInfoDO;
import com.yn.common.model.zy.TOrganInfoDO;
import com.yn.common.model.zyorder.ZyOrder;
import com.yn.common.page.BasePage;
import com.yn.common.request.sc.PageParamRequest;
import com.yn.common.request.zy.DoctorAddRequest;
import com.yn.common.utils.PhoneValidator;
import com.yn.service.dao.zy.TDoctorInfoMapper;
import com.yn.service.service.IDoctorDepartmentLinkService;
import com.yn.service.service.IOrganDepartmentService;
import com.yn.service.service.SystemAttachmentService;
import com.yn.service.zy.TDoctorInfoService;
import com.yn.service.zy.TOrganInfoService;
import com.yn.service.zy.model.dto.OrganDepartmentDTO;
import com.yn.service.zy.model.dto.TDoctorInfoOutDTO;
import com.yn.service.zy.model.query.TDoctorInfoQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class TDoctorInfoServiceImpl extends ServiceImpl<TDoctorInfoMapper, TDoctorInfoDO> implements TDoctorInfoService {

    @Resource
    private TDoctorInfoMapper tDoctorInfoMapper;
    @Resource
    private IDoctorDepartmentLinkService doctorDepartmentLinkService;

    @Resource
    private IOrganDepartmentService organDepartmentService;

    @Resource
    private SystemAttachmentService systemAttachmentService;

    @Resource
    private TOrganInfoService organService;

    /**
     * 分页获取专家列表
     *
     * @param query
     * @param basePage
     * @return
     */
    @Override
    public IPage<TDoctorInfoOutDTO> listPageByQuery(TDoctorInfoQuery query, BasePage basePage) {
        IPage page = new Page(basePage.getPage(), basePage.getLimit());
        return tDoctorInfoMapper.listPageByQuery(query, page);
    }

    /**
     * 获取专家详情
     *
     * @param doctorId
     * @return
     */
    @Override
    public TDoctorInfoOutDTO getInfo(Integer doctorId) {
        TDoctorInfoDO doctorInfo = getById(doctorId);
        if (doctorInfo == null) {
            throw new TransitException("专家不存在");
        }
        TDoctorInfoOutDTO response = TDoctorInfoOutDTO.transform(doctorInfo);
        //根据医生id找科室id
        List<DoctorDepartmentLink> linkList = doctorDepartmentLinkService.lambdaQuery().eq(DoctorDepartmentLink::getDoctorId, doctorId).list();
        if (CollUtil.isEmpty(linkList)) {
            throw new TransitException("未找到医生对应的科室");
        }
        // 科室id集合
        List<Integer> departmentIds = linkList.stream().map(DoctorDepartmentLink::getBelongingDepartmentId).collect(Collectors.toList());
        if (CollUtil.isEmpty(departmentIds)) {
            throw new TransitException("未找到医生对应的科室");
        }
        //根据科室id集合获取科室信息
        List<OrganDepartment> organDepartments = organDepartmentService.listByIds(departmentIds);
        if (CollUtil.isEmpty(organDepartments)) {
            throw new TransitException("医生没有关联的科室");
        }
        //获取科室信息
        StringBuilder builder = new StringBuilder();
        for (OrganDepartment department : organDepartments) {
            String departmentName = department.getDepartmentName();
            builder.append(departmentName).append(",");
        }
        if (response != null) {
            response.setDepartmentNames(builder.substring(0, builder.length() - 1));
        }
        return response;
    }


    /**
     * 分页获取专家列表
     *
     * @param query 查询参数
     * @param pageRequest 分页参数
     * @return
     */
    @Override
    public BasePage<TDoctorInfoOutDTO> listPageByQuery1(TDoctorInfoQuery query, PageParamRequest pageRequest) {
        PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit());

        LambdaQueryWrapper<TDoctorInfoDO> queryWrapper = new LambdaQueryWrapper<>();
        //构建查询条件
        queryWrapper.eq(StrUtil.isNotEmpty(query.getAreaCode()), TDoctorInfoDO::getBelongingRegion, query.getAreaCode());
        queryWrapper.eq(query.getHospitalId() != null && query.getHospitalId() > 0, TDoctorInfoDO::getOrganInfoId, query.getHospitalId());
        queryWrapper.eq(query.getDeptId() != null && !query.getDeptId().isEmpty(), TDoctorInfoDO::getBelongingDepartmentId, query.getDeptId());
        queryWrapper.like(StrUtil.isNotEmpty(query.getLeverName()), TDoctorInfoDO::getDoctorLever, query.getLeverName());
        if (StrUtil.isNotEmpty(query.getKeyword())) {
            queryWrapper.and(i -> i.or().like(TDoctorInfoDO::getDoctorName, query.getKeyword())
                    .or().like(TDoctorInfoDO::getDoctorIntro, query.getKeyword())
                    .or().like(TDoctorInfoDO::getProfessionalField, query.getKeyword())
                    .or().like(TDoctorInfoDO::getEducation, query.getKeyword())
                    .or().like(TDoctorInfoDO::getBelongingHospital, query.getKeyword()));
        }

        //查询
        List<TDoctorInfoDO> tDoctorInfoDOS = baseMapper.selectList(queryWrapper);
        if (CollUtil.isEmpty(tDoctorInfoDOS)) {
            return BasePage.restPage(new ArrayList<>());
        }

        //转page对象
        BasePage<TDoctorInfoDO> basePage = BasePage.restPage(tDoctorInfoDOS);

        //初始化集合
        ArrayList<TDoctorInfoOutDTO> arrayList = new ArrayList<>(tDoctorInfoDOS.size());

        //收集doctorIds集合
        List<Integer> doctorIds = tDoctorInfoDOS.stream().map(TDoctorInfoDO::getId).collect(Collectors.toList());

        if (CollUtil.isEmpty(doctorIds)) {
            return BasePage.restPage(new ArrayList<>());
        }

        //根据doctorIds集合获取医生科室关联表信息
        List<DoctorDepartmentLink> allLinks = doctorDepartmentLinkService.lambdaQuery()
                .in(DoctorDepartmentLink::getDoctorId, doctorIds)
                .list();

        if (CollUtil.isEmpty(allLinks)) {
            return BasePage.restPage(new ArrayList<>());
        }

        // 按 doctorId 分组转Map<doctorId,List<departmentIds>>
        Map<Integer, List<Integer>> linkMap = allLinks.stream()
                .collect(Collectors.groupingBy(DoctorDepartmentLink::getDoctorId,
                        Collectors.mapping(DoctorDepartmentLink::getBelongingDepartmentId, Collectors.toList())));
        log.info("linkMap: {}", linkMap);
        for (TDoctorInfoDO tDoctorInfoDO : tDoctorInfoDOS) {
            TDoctorInfoOutDTO dto = TDoctorInfoOutDTO.transform(tDoctorInfoDO);
            List<Integer> departmentIds = linkMap.get(tDoctorInfoDO.getId());

            if (CollUtil.isEmpty(departmentIds)) {
                throw new TransitException("医生没有关联科室");
            }
            //根据科室id集合获取科室信息
            List<OrganDepartment> organDepartments = organDepartmentService.listByIds(departmentIds);

            if (CollUtil.isEmpty(organDepartments)) {
                throw new TransitException("医生没有关联的科室");
            }
            StringBuilder builder = new StringBuilder();
            for (OrganDepartment department : organDepartments) {
                String departmentName = department.getDepartmentName();
                builder.append(departmentName).append(",");
            }
            if (dto != null) {
                dto.setDepartmentNames(builder.substring(0, builder.length() - 1));
            }
            arrayList.add(dto);
        }

        BasePage<TDoctorInfoOutDTO> tDoctorInfoOutDTOBasePage = BasePage.restPage(arrayList);
        BeanUtils.copyProperties(basePage, tDoctorInfoOutDTOBasePage, "list");
        return tDoctorInfoOutDTOBasePage;
    }

    /**
     * 新增专家
     *
     * @param request 新增专家请求对象
     * @return
     */
    @Override
    @Transactional
    public void saveDoctorInfo(DoctorAddRequest request) {
        // 手机号码验证
        boolean valid = PhoneValidator.isValid(request.getPhoneNumber());
        if (!valid) {
            throw new TransitException( "手机号码格式错误");
        }
        //图片验证
        boolean isTrueUrl = systemAttachmentService.selectByUrl(request.getHeadImageUrl());
        if (!isTrueUrl) {
            throw new TransitException( "图片路径不正确");
        }
        //根据联系电话查询是否已经存在该记录
        TDoctorInfoDO one = lambdaQuery().eq(TDoctorInfoDO::getPhoneNumber, request.getPhoneNumber())
                .eq(TDoctorInfoDO::getIsDelTag, 0).one();
        if (one != null) {
            throw new TransitException("该联系电话已存在");
        }
        TDoctorInfoDO doctorInfoDO = DoctorAddRequest.transform(request);
        if (doctorInfoDO == null) {
            throw new TransitException("机构不存在");
        }
        TOrganInfoDO organInfoDO = organService.getById(doctorInfoDO.getOrganInfoId());
        if (organInfoDO == null) {
            throw new TransitException("所属医院不存在");
        }
        doctorInfoDO.setBelongingHospital(organInfoDO.getOrganName());
        boolean save = save(doctorInfoDO);
        if (!save) {
            throw new TransitException("添加医生信息失败");
        }
        ArrayList<DoctorDepartmentLink> list = new ArrayList<>();
        if (CollUtil.isNotEmpty(request.getBelongingDepartmentIds())) {
            request.getBelongingDepartmentIds().forEach(id -> {
                DoctorDepartmentLink doctorDepartmentLink = new DoctorDepartmentLink();
                doctorDepartmentLink.setDoctorId(doctorInfoDO.getId());
                doctorDepartmentLink.setBelongingDepartmentId(id);
                list.add(doctorDepartmentLink);
            });
        }
        boolean b = doctorDepartmentLinkService.saveBatch(list);
        if (!b) {
            throw new TransitException("添加医生部门关系失败");
        }
    }

    /**
     * 修改医生信息
     * @param request 修改专家信息请求对象
     */
    @Override
    @Transactional
    public void modifyDoctorInfo(DoctorAddRequest request) {
        // 手机号码验证
        boolean valid = PhoneValidator.isValid(request.getPhoneNumber());
        if (!valid) {
            throw new TransitException( "手机号码格式错误");
        }
        //头像验证
        boolean isTrueUrl = systemAttachmentService.selectByUrl(request.getHeadImageUrl());
        if (!isTrueUrl) {
            throw new TransitException( "图片路径不正确");
        }
        if (request.getId() == null) {
            throw new TransitException("修改医生信息失败");
        }
        TDoctorInfoDO doctorInfoDO = DoctorAddRequest.transform(request);
        if (doctorInfoDO == null) {
            throw new TransitException("机构不存在");
        }
        TOrganInfoDO organInfoDO = organService.getById(doctorInfoDO.getOrganInfoId());
        if (organInfoDO == null) {
            throw new TransitException("所属医院不存在");
        }
        doctorInfoDO.setBelongingHospital(organInfoDO.getOrganName());
        boolean updateById = updateById(doctorInfoDO);
        if (!updateById) {
            throw new TransitException("修改医生信息失败");
        }
        //删除医生部门关系
        doctorDepartmentLinkService.lambdaUpdate()
                .eq(DoctorDepartmentLink::getDoctorId, request.getId())
                .remove();
        ArrayList<DoctorDepartmentLink> list = new ArrayList<>();
        if (CollUtil.isNotEmpty(request.getBelongingDepartmentIds())) {
            request.getBelongingDepartmentIds().forEach(id -> {
                DoctorDepartmentLink doctorDepartmentLink = new DoctorDepartmentLink();
                doctorDepartmentLink.setDoctorId(request.getId());
                doctorDepartmentLink.setBelongingDepartmentId(id);
                list.add(doctorDepartmentLink);
            });
        }
        boolean b = doctorDepartmentLinkService.saveBatch(list);
        if (!b) {
            throw new TransitException("修改失败");
        }
    }

    /**
     * 删除专家
     * @param doctorId 专家id
     * @return
     */
    @Override
    @Transactional
    public void deleteDoctorInfo(Integer doctorId) {
        boolean b = this.removeById(doctorId);
        if (!b) {
            throw new TransitException("信息已被删除");
        }
        boolean b1 = doctorDepartmentLinkService.lambdaUpdate()
                .eq(DoctorDepartmentLink::getDoctorId, doctorId)
                .remove();
        if (!b1) {
            throw new TransitException("删除失败");
        }
    }
}
